/**
 * @param {number[]} nums
 * @return {number}
 */
// 这个是 ai 的回答，我感觉比下面的答案要好一点
// 但是我的答案比较的好理解，因为用的是 sort 方法来进行的排序
// 所以算法的事件复杂度是 O(nlogn)
// 但是 ai 回答的算法的时间复杂度是 O(n)
// 是符合题目的要求的
// 但是写的话，还是推荐使用我的写法，这样比较的简答
var longestConsecutive = function (nums) {
  // 将数组元素存入Set，便于快速查找
  const numSet = new Set(nums);
  let longestStreak = 0;

  // 遍历每个数字
  for (const num of numSet) {
    // 只处理序列的起始数字（即num-1不存在于集合中）
    if (!numSet.has(num - 1)) {
      let currentNum = num;
      let currentStreak = 1;

      // 连续检查后续数字
      while (numSet.has(currentNum + 1)) {
        currentNum += 1;
        currentStreak += 1;
      }

      // 更新最长序列长度
      longestStreak = Math.max(longestStreak, currentStreak);
    }
  }

  return longestStreak;
};

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
  if (!nums.length) return 0;
  nums = Array.from(new Set(nums.sort((a, b) => a - b)));
  let arr = [];
  let flag = [];
  for (let i = 0, j = i + 1; i < nums.length; i++, j++) {
    if (nums[j] - nums[i] === 1) {
      flag.push(nums[i]);
    } else {
      flag.push(nums[i]);
      arr.push(flag.length);
      flag = [];
    }
  }

  return Math.max(...arr);
};

/**
 * @param {number[]} nums
 * @return {number}
 */
/* 
  1. 将数组元素存入 set 中
  2. 遍历nums，如果 当前项 - 1 存在于 set ，说明当前项不是连续序列的起点，忽略，继续遍历
  3. 如果当前项没有“左邻居”，它就是连续序列的起点，循环查看当前项连续的右邻居有多少个
  4. 返回最长的连续次数
*/
var longestConsecutive = function (nums) {
  // 把题目中数组的数字全部放入set中，一来去重，二来方便快速查找
  const set = new Set(nums);
  let max = 0;
  for (let [key, a] of set.entries()) {
    // 没有左邻居，是序列的起点
    if (!set.has(a - 1)) {
      let count = 1;
      let cur = a;
      // 有右邻居，看连续的右邻居有多少个
      while (set.has(cur + 1)) {
        cur++;
        count++;
      }
      // 存放最大的连续邻居的值
      max = Math.max(max, count);
    }
  }
  return max;
};
